<script>
  const formProperties = [
    'disabled',
    'size',
    'statusIcon',
    'inlineMessage',
    'autoLabelWidth',
    'hideRequiredAsterisk',
    '$emit',
    'validate',
    'clearValidate'
  ]

  const formMethod = ['$emit', 'validate', 'clearValidate']

  export default {
    name: 'FormBlock',
    inject: {
      elForm: {
        default: {}
      }
    },
    provide() {
      return {
        elForm: this.formConfig
      }
    },
    props: {
      blockTitle: String,
      active: Boolean,
      enabled: Boolean,
      disabled: Boolean,
      wrapRow: {
        type: Boolean,
        default: true
      },
      gutter: {
        type: Number,
        default: 20
      },
      collapse: Boolean
    },
    data() {
      const formConfig = {}
      formProperties.forEach(key => {
        formConfig[key] = null
      })
      return {
        expand: true,
        formConfig
      }
    },
    computed: {
      formCfg() {
        const formConfig = {
          enabled: this.enabled,
          forbidden: this.disabled
        }
        formProperties.forEach(key => {
          formConfig[key] = this.elForm[key]
        })
        return formConfig
      }
    },
    watch: {
      collapse: {
        immediate: true,
        handler(newVal) {
          this.expand = !newVal
        }
      },
      formCfg: {
        immediate: true,
        handler() {
          this.formConfig.disabled = this.available()
          formProperties.forEach(key => {
            if (key !== 'disabled') {
              if (formMethod.includes(key)) {
                this.formConfig[key] = this.elForm[key]?.bind(this.elForm)
              } else {
                this.formConfig[key] = this.elForm[key]
              }
            }
          })
        }
      }
    },
    mounted() {
      this.dispatch('FormView', 'FormView.addTab', [this])
    },
    beforeDestroy() {
      this.dispatch('FormView', 'FormView.removeTab', [this])
    },
    methods: {
      available() {
        return this.disabled ? this.disabled : this.enabled ? !this.enabled : this.elForm.disabled
      },
      dispatch(componentName, eventName, params) {
        let parent = this.$parent || this.$root
        let name = parent.$options.name

        while (parent && (!name || name !== componentName)) {
          parent = parent.$parent
          if (parent) {
            name = parent.$options.name
          }
        }
        if (parent) {
          parent.$emit.apply(parent, [eventName].concat(params))
        }
      },
      renderDefault() {
        const { wrapRow, gutter, formConfig, $scopedSlots } = this
        return wrapRow ? (
          <ElRow gutter={gutter}>{$scopedSlots.default({ disabled: formConfig.disabled })}</ElRow>
        ) : (
          $scopedSlots.default({ disabled: formConfig.disabled })
        )
      },
      toggle() {
        this.expand = !this.expand
      },
      open() {
        this.expand = true
      }
    },
    render() {
      const { renderDefault, blockTitle, active, expand, toggle } = this
      return (
        <div class={['form-block', { 'default-active': active }]}>
          <div class="form-block-title" on-click={toggle}>
            <span class="flex-item">{blockTitle}</span>{' '}
            <i class={expand ? 'el-icon-arrow-down' : 'el-icon-arrow-right'}></i>
          </div>
          <ElCollapseTransition>
            <div vShow={expand}>{renderDefault()}</div>
          </ElCollapseTransition>
        </div>
      )
    }
  }
</script>

<style lang="scss">
  .form-block {
    padding-bottom: 10px;
    background-color: #fff;
  }

  .form-block-title {
    @include flex-row;
    align-items: center;
    height: 30px;
    margin: 0 0 10px;
    padding: 0 10px;
    color: #333;
    font-weight: bold;
    font-size: 14px;
    line-height: 30px;
    background-color: #f3f5fb;
    cursor: pointer;
  }
</style>
